package com.remoter.context.spring.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.remoter.api.configure.IConfiguration;
import com.remoter.api.configure.support.AbstractConfiguration;
import com.remoter.api.context.IContextService;
import com.remoter.api.context.support.Importer;
import com.remoter.api.extension.support.ExtensionLoader;
import com.remoter.api.util.Final;

public class ConsumerBean implements FactoryBean<Object>,ApplicationContextAware,InitializingBean,DisposableBean{
	
	private String name;
	private Class<?> type;
	
    private transient ApplicationContext applicationContext;
    private IContextService contextService;
    
    public ConsumerBean(String name,Class<?> type){
    	this.name = name;
    	this.type = type;
    	IConfiguration configuration = AbstractConfiguration.getConfiguration();
    	this.contextService = ExtensionLoader.getService(IContextService.class,configuration.getOption(Final.O_SERVER_CONTEXT));
    }
    
	@Override
	public void destroy() throws Exception {
		
	}
	@Override
	public void afterPropertiesSet() throws Exception {
		
	}
	@Override
	public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {
		this.applicationContext = applicationContext;
	}
	@Override
	public Object getObject() throws Exception {
		Importer importer = this.contextService.createImporter(this.name,this.type);
		this.contextService.attachImporter(importer);
		return importer.getProxy(this.type);
	}
	@Override
	public Class<?> getObjectType() {
		return this.type;
	}
	@Override
	public boolean isSingleton() {
		return true;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Class<?> getType() {
		return type;
	}

	public void setType(Class<?> type) {
		this.type = type;
	}

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}
}